<?php
/**
 * @copyright 2025 银杏WMS
 * @author 银杏WMS
 * @version 1.0
 * @license http://www.hhyx.xyz
 * @developer Lhf
 */

namespace app\admin\model\yxerp;

use think\Model;
use think\facade\Db;
use think\facade\Event;
use think\model\concern\SoftDelete;

class WarehouseOperation extends Model
{
    // 表名
    protected $name = 'yxerp_warehouse_operation';
    
    // 自动写入时间戳
    protected $autoWriteTimestamp = true;
    
    // 追加属性
    protected $append = [
        'status_text',
        'direction_text'
    ];
    
    /**
     * 方向列表
     */
    public static function getDirectionList()
    {
        return [
            1 => '入库',
            2 => '出库'
        ];
    }
    
    /**
     * 状态列表
     */
    public static function getStatusList()
    {
        return [
            1 => '草稿',
            2 => '已审核',
            3 => '已取消'
        ];
    }
    
    /**
     * 获取方向文本
     */
    public function getDirectionTextAttr($value, $data)
    {
        $value = $value ? $value : $data['direction'];
        $list = $this->getDirectionList();
        return isset($list[$value]) ? $list[$value] : '';
    }
    
    /**
     * 获取状态文本
     */
    public function getStatusTextAttr($value, $data)
    {
        $value = $value ? $value : $data['status'];
        $list = $this->getStatusList();
        return isset($list[$value]) ? $list[$value] : '';
    }
    
    /**
     * 关联明细
     */
    public function details()
    {
        return $this->hasMany('WarehouseOperationDetail', 'operation_id');
    }
    
    /**
     * 关联仓库
     */
    public function warehouse()
    {
        return $this->belongsTo('Warehouse', 'warehouse_id');
    }
    
    /**
     * 关联操作类型
     */
    public function operationType()
    {
        return $this->belongsTo('WarehouseOperationType', 'operation_type_id');
    }
    
    /**
     * 生成操作单号
     */
    public static function generateOperationNo($prefix = 'WO')
    {
        $date = date('Ymd');
        $key = "warehouse_operation_no_{$date}";
        
        // 获取当日序号
        $sequence = cache($key) ?: 1;
        
        // 生成单号
        $operationNo = $prefix . $date . str_pad($sequence, 4, '0', STR_PAD_LEFT);
        
        // 更新序号
        cache($key, $sequence + 1, 86400);
        
        return $operationNo;
    }
    
    /**
     * 审核操作
     */
    public function approve($operationId, $userId, $userName)
    {
        Db::startTrans();
        try {
            // 获取操作详情
            $operation = self::with(['details'])->where('id', $operationId)->find();
            if (!$operation) {
                throw new \Exception('出入库单据不存在');
            }
            
            if ($operation['status'] != 1) {
                throw new \Exception('只有草稿状态的单据才能审核');
            }
            
            // 更新审核信息
            $operation->status = 2;
            $operation->approve_user_id = $userId;
            $operation->approve_user = $userName;
            $operation->approve_time = time();
            $operation->save();
            
            // 触发审核事件
            Event::trigger('warehouse_operation_approved', $operation);
            
            Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollback();
            throw $e;
        }
    }
    
    /**
     * 取消操作
     */
    public function cancel($operationId, $userId, $userName)
    {
        Db::startTrans();
        try {
            // 获取操作详情
            $operation = self::where('id', $operationId)->find();
            if (!$operation) {
                throw new \Exception('出入库单据不存在');
            }
            
            if ($operation['status'] == 2) {
                throw new \Exception('已审核的单据不能取消，请先反审核');
            }
            
            // 更新状态
            $operation->status = 3;
            $operation->save();
            
            // 触发取消事件
            Event::trigger('warehouse_operation_cancelled', $operation);
            
            Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollback();
            throw $e;
        }
    }
    
    /**
     * 反审核操作
     */
    public function unapprove($operationId, $userId, $userName)
    {
        Db::startTrans();
        try {
            // 获取操作详情
            $operation = self::with(['details'])->where('id', $operationId)->find();
            if (!$operation) {
                throw new \Exception('出入库单据不存在');
            }
            
            if ($operation['status'] != 2) {
                throw new \Exception('只有已审核状态的单据才能反审核');
            }
            
            // 检查库存是否足够（如果是出库操作）
            if ($operation['direction'] == 2) {
                foreach ($operation['details'] as $detail) {
                    // 检查当前库存是否足够
                    $inventory = Inventory::where([
                        'warehouse_id' => $operation['warehouse_id'],
                        'product_id' => $detail['product_id'],
                        'batch_no' => $detail['batch_no'] ?: ''
                    ])->find();
                    
                    if (!$inventory || $inventory['quantity'] < $detail['quantity']) {
                        throw new \Exception('产品'.$detail['product_name'].'当前库存不足，无法反审核');
                    }
                }
            }
            
            // 更新审核信息
            $operation->status = 1;
            $operation->approve_user_id = null;
            $operation->approve_user = null;
            $operation->approve_time = null;
            $operation->save();
            
            // 触发反审核事件
            Event::trigger('warehouse_operation_unapproved', $operation);
            
            Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollback();
            throw $e;
        }
    }
} 